home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
dbwrendr.zip
/
SOURCE
/
VAL.C
< prev
Wrap
C/C++ Source or Header
|
1989-04-17
|
16KB
|
394 lines
/************************************************************************
* *
* Copyright (c) 1987, David B. Wecker *
* All Rights Reserved *
* *
* This file is part of DBW_Render *
* *
* DBW_Render is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY. No author or distributor accepts *
* responsibility to anyone for the consequences of using it or for *
* whether it serves any particular purpose or works at all, unless *
* he says so in writing. Refer to the DBW_Render General Public *
* License for full details. *
* *
* Everyone is granted permission to copy, modify and redistribute *
* DBW_Render, but only under the conditions described in the *
* DBW_Render General Public License. A copy of this license is *
* supposed to have been given to you along with DBW_Render so you *
* can know your rights and responsibilities. It should be in a file *
* named COPYING. Among other things, the copyright notice and this *
* notice must be preserved on all copies. *
************************************************************************
* *
* Authors: *
* DBW - David B. Wecker *
* *
* Versions: *
* V1.0 870125 DBW - First released version *
* *
************************************************************************/
#define MODULE_VAL
#include "ray.h"
void getval(val,np,p,d,atten,ambientlight)
vector val,
p,
d;
node *np;
float atten;
int ambientlight;
{
vector pseudodirection,
pseudointensity,
tp,
lightdir,
lightint,
penumbra,
transparency,
best_p,
nval,
n,
r,
temp,
specintensity,
diffuse,
v1;
float best_t,
ndotdir,
t,
texture,
td,
pointdist,
umbscale;
float ndotd,
ambientscale;
int hitnext,
lit,
i,
itd;
node *bouncenp,
*occlude;
vector light_atten[MAXLIT];
int l_objcounter;
float l_distances[MAXOBJ];
node *l_objpairs[MAXOBJ];
vector l_points[MAXOBJ];
if (allopaque == 0)
{ /* If not opaque,then save the ray intersection list */
l_objcounter = g_objcounter;
for (i = 0; i < l_objcounter; i++)
{
l_distances[i] = g_distances[i];
l_objpairs[i] = g_objpairs[i];
veccopy(g_points[i],l_points[i]);
}
}
veczero(val); /* start with output value of zero */
findnormal(np,p,n);
ndotd = DOT(n,d);
if (ndotd > 0.0)
{ /* We're looking at surface's back side */
ndotd = -ndotd;
n[0] = -n[0]; /* Flip the normal */
n[1] = -n[1];
n[2] = -n[2];
}
/* Initialize the light attenuation values with 'not-yet-computed' flag */
for (lit = 0; lit < numlits; lit++)
light_atten[lit][0] = -99.9;
/* Apply procedural texture */
gettex(diffuse,np,p,n);
/*---------------------------------------------------------------------*/
/* Compute diffuse reflection intensity */
if (diffuse[0] > 0.01 || diffuse[1] > 0.01 || diffuse[2] > 0.01)
{
/* First,compute light shining directly on this point */
for (lit = 0; lit < numlits; lit++)
{
veccopy(light[lit].direction,lightdir);
veccopy(light[lit].intensity,lightint);
pointdist = 0.0;
if (light[lit].kind != 0)
{ /* If point source,compute local direction */
vecsub(lightdir,p,lightdir);
pointdist = NORM(lightdir); /* distance to point light source */
if (pointdist == 0.0)
pointdist = 0.01;
umbscale = light[lit].distscale;
umbscale /= pointdist * pointdist;
vecscale(umbscale,lightint,lightint);
CV(rnd(),rnd(),rnd(),penumbra);
if (rnd() < 0.5)
penumbra[0] = -penumbra[0];
if (rnd() < 0.5)
penumbra[1] = -penumbra[1];
if (rnd() < 0.5)
penumbra[2] = -penumbra[2];
normalize(penumbra); /* penumbra is now random unit vector */
umbscale = rnd();
umbscale -= 0.05;
umbscale *= light[lit].radius;
vecscale(umbscale,penumbra,penumbra);
vecsum(penumbra,lightdir,lightdir);
normalize(lightdir);
}
/* Now that we know where the light is shining from,compute diffuse
(lamertian) reflection */
ndotdir = DOT(n,lightdir);
if (ndotdir > 0.0)
{
vecmul(lightint,diffuse,nval);
vecscale(ndotdir,nval,nval);
}
else
{
veczero(nval); /* self shadowing -- backside of spheres,etc. */
}
/* If the computed diffuse surface brightness is above a certain
threshold level,then compute the shadow attenuation */
if (nval[0] > 0.01 || nval[1] > 0.01 || nval[2] > 0.01)
{
getatten(light_atten[lit],p,lightdir,lit,pointdist);
vecmul(nval,light_atten[lit],nval); /* attenuate */
}
vecsum(nval,val,val); /* Sum up for all light sources */
} /* for */
/*---------------------------------------------------------------------*/
/* Next,compute light shining indirectly from any surfaces on this */
/* point. This is done to approximate true ambient illumination. */
for (lit = 0; lit < ambientlight; lit++)
{
ambientscale = 1.0 / (float) ambientlight;
/* ?? not sure how to factor in distance from diffuse reflector */
CV(rnd(),rnd(),rnd(),lightdir);
if (rnd() < 0.5)
lightdir[0] = -lightdir[0];
if (rnd() < 0.5)
lightdir[1] = -lightdir[1];
if (rnd() < 0.5)
lightdir[2] = -lightdir[2];
normalize(lightdir); /* lightdir is now random unit vector */
ndotdir = DOT(n,lightdir);
if (ndotdir < 0.0)
{ /* if not in upper hemisphere,invert it */
lightdir[0] = -lightdir[0];
lightdir[1] = -lightdir[1];
lightdir[2] = -lightdir[2];
ndotdir = -ndotdir;
}
/* okay,now the direction is known. What is visible there? */
dodirection(nval,p,lightdir,ambientscale,
ambientlight * amblitnum / amblitdenom);
val[0] += nv